﻿using System;
using System.Collections.Generic;
using EzDesk.Apps.Data.ProjectModule;
using EzDesk.Apps.Interface.ProjectModule;
using EzDesk.Apps.Model.ProjectModule;
using EzDesk.Utility.ServiceStatusInfo;

using System.Linq;
using System.Data.Linq;

namespace EzDesk.Apps.ServiceImpl.ProjectModule
{
    public partial class ProjectService : IProjectService
    {
        #region private methods

        private List<MemberInProject> getMemberInProjectList(string memberstring)
        {
            var members = _ezApiClient.GetSimpleUserInfos(memberstring);
            var memberInProjectList = new List<MemberInProject> { };
            memberInProjectList.AddRange(
                members.Select(simpleUser =>
                               new MemberInProject
                               {
                                   Id = Guid.NewGuid(),
                                   UserId = simpleUser.Id
                               })
                );
            return memberInProjectList;
        }
        #endregion


        public StatusInfo<List<Project>> GetProjectsForUser(Guid userId)
        {
            return StatusInfo.Wrap(() =>
                    EzDeskProjectContainer.Go(container =>
                    {
                        var userProjets =
                            container.MemberInProjectSet.Where(
                                mip => mip.UserId == userId);

                        foreach (var memberInProject in userProjets)
                        {
                            container.LoadProperty(memberInProject,
                                                mip => mip.Project);
                            container.LoadProperty(memberInProject.Project, p => p.MemberInProject);
                        }
                        return
                            userProjets.Select(up => up.Project).ToList();
                    }));
        }

        public StatusInfo<Project> GetProjectById(Guid projectId)
        {
            return StatusInfo.Wrap(
                () =>
                EzDeskProjectContainer.Go(
                    container =>
                    {
                        Action<Project> getProjectTree = null;

                        getProjectTree = new Action<Project>(
                            project =>
                            {
                                container.LoadProperty(
                                    project,
                                    p => p.MemberInProject);
                                container.LoadProperty(
                                    project,
                                    p =>
                                    p.SubProjects);
                                foreach (
                                    var subProject in project.SubProjects)
                                {
                                    getProjectTree(subProject);
                                }
                                container.LoadProperty(project,
                                                       p =>
                                                       p.Workitem);
                            }
                            );

                        var finalProject =
                            container.ProjectSet.First(
                                p => p.Id == projectId);
                        getProjectTree(finalProject);
                        return finalProject;
                    }));
        }

        public StatusInfo<Project> CreateNewProject(Project project)
        {
            return StatusInfo.Wrap(()
                =>
            {
                using (var db = new EzDeskProjectContainer())
                {
                    db.ContextOptions.ProxyCreationEnabled = false;
                    db.ContextOptions.LazyLoadingEnabled = true;

                    project.Id = Guid.NewGuid();
                    project.Name = project.Name;
                    project.Code = project.Code;
                    project.CreateOn = DateTime.Now;
                    project.MemberString = project.MemberString ?? "";
                    var projectStatus = db.ProjectStatusSet.FirstOrDefault(s => s.StatusName == "准备中");
                    project.ProjectStatus =projectStatus ?? new ProjectStatus(){StatusName = "准备中"};

                    var memberInProjecList = getMemberInProjectList(project.MemberString);
                    project.MemberInProject = memberInProjecList;
                    db.ProjectSet.AddObject(project);
                    db.SaveChanges();

                    return project;
                }
            }
                );
        }

        public StatusInfo UpdateDescription(Guid projectId, string description)
        {
            return StatusInfo.Wrap(()
             =>
            {
                using (var db = new EzDeskProjectContainer())
                {
                    db.ContextOptions.ProxyCreationEnabled = false;

                    var project = db.ProjectSet.First(p => p.Id == projectId);
                    project.Description = description;
                    db.SaveChanges();
                }
            }
            );
        }

        public StatusInfo UpdateProjectMember(Guid projectId, string memberString)
        {
            return StatusInfo.Wrap(()
             =>
            {
                using (var db = new EzDeskProjectContainer())
                {
                    db.ContextOptions.ProxyCreationEnabled = false;

                    var project = db.ProjectSet.First(p => p.Id == projectId);
                    project.MemberString = memberString;

                    var memberInProjects = db.MemberInProjectSet.Where(p => p.ProjectId == project.Id);
                    foreach (var memberInProject in memberInProjects)
                    {
                        db.MemberInProjectSet.DeleteObject(memberInProject);
                    }
                    db.SaveChanges();

                    project.MemberInProject = getMemberInProjectList(project.MemberString); ;

                    db.SaveChanges();

                }
             }
             );
        }

    }
}
